package two.chapter_1.c1_1;

public class Ex1_1_33 {

    public static void main(String[] args) {
        double[]x={1,2};
        double[]y={2,3};
        //StdOut.println(Matrix.dot(x,y));//8

        double[][] a={{2,1,1},{3,1,1}};  //2行3列
        double[][] b={{2,2},{3,3},{4,4}};//3行2列
        double result[][]=Matrix.mult(a,b);
        Printer.printArray(result);


        /*    [1,3] *  [2,1,1]   =[1*2+3*2,1*1+3*1,1*1+3*1]  =[8,4,4]
         * [2,1,1]*/

       /* x=new double[]{1,3};
        a=new double[][]{{2,1,1},{2,1,1}};
        double result[]=Matrix.mult(x,a);
        Printer.printArray(result);*/
    }


    private static class Matrix {

        /**
         * 向量点积
         *
         * @param x
         * @param y
         * @return
         */
        public static double dot(double[] x, double[] y) {
            //检查两个数组长度是否一致
            if (x.length != y.length) {
                throw new RuntimeException("two array's length must equal ");
            }

            int n = x.length;
            double sum = 0;
            for (int i = 0; i < n; i++) {
                sum += x[i] * y[i];
            }

            return sum;
        }

        /**
         * 矩阵乘法    (M*N)  *  (N*P ) -->  (M*P)
         * 向量是特殊的矩阵所以也满足矩阵的乘法
         * @param a M行N列
         * @param b N行P列
         * @return M行P列
         */
        public static double[][] mult(double[][] a, double[][] b) {
            int m = a.length;
            int n = a[0].length;

            int bm = b.length;
            int bn = b[0].length;

            if (n != bm) {
                throw new RuntimeException("array a's col must equal array b's row ");
            }
            double[][] result = new double[m][bn];
            for (int i = 0; i < m; i++) {//m行
                for (int k = 0; k < bn; k++) {//p列
                    for (int j = 0; j < n; j++) {
                        result[i][k] += a[i][j] * b[j][k];
                    }
                }
            }

            return result;
        }

        /**
         * 矩阵转置
         *
         * @param a
         * @return
         */
        public static double[][] transpose(double[][] a) {
            int m = a.length;
            int n = a[0].length;
            double[][] transposed = new double[m][n];
            for (int j = 0; j < n; j++) {//列
                for (int i = 0; i < m; i++) {//行
                    transposed[j][i] = a[i][j];
                }
            }

            return transposed;
        }

        /**向量是特殊的矩阵
         * 矩阵和向量乘法
         *
         * @param a m行n列
         * @param x n行1列
         * @return  m行1列
         */
        public static double[] mult(double[][] a, double[] x) {
            int m = a.length;
            int n = a[0].length;
            int xm = x.length;
            if (n!=xm){
                throw  new RuntimeException();
            }
            double[] result = new double[m];
            for (int i = 0; i < m; i++) {
                for (int j = 0; j < n; j++) {
                    result[i]+=a[i][j]*x[j];
                }

            }
            return result;
        }

        /**
         * 向量和矩阵乘法
         * 向量各个数分别乘以矩阵第i列之和为结果向量中的第行元素
         * [1,3] *  [2,1,1]   =[1*2+3*2,1*1+3*1,1*1+3*1]  =[8,4,4]
         * [2,1,1]
         *
         * @param a
         * @param y 向量的列数需要和矩阵的行数一致
         * @return
         */
        public static double[] mult(double[] y, double[][] a) {
            int m = a.length;
            int n = a[0].length;

            int ym = y.length;

            if (ym != m) {
                throw new RuntimeException();
            }
            double result[]=new double[n];
            for (int i = 0; i < n; i++) {//列
                for (int j = 0; j < m; j++) {//矩阵的行数 也是 向量的列数
                    result[i]+=y[j] * a[j][i];
                }
            }

            return result;
        }
    }


}
